package cn.xuexiluxian.open.admin.controller.common;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.xuexiluxian.open.common.constant.Constants;
import cn.xuexiluxian.open.common.response.ResponseResult;
import cn.xuexiluxian.open.common.utils.FileUtils;
import cn.xuexiluxian.open.common.utils.StringUtils;
import cn.xuexiluxian.open.system.model.vo.SystemUploadVO;
import com.alibaba.fastjson.JSONObject;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 通用请求处理
 */
@Slf4j
@RestController
@RequestMapping("upload")
public class UploadController {
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
    @Value("${common.host}")
    private String host;
    @Value("${common.uploadPath}")
    private String uploadDir;


    /**
     * 通用上传请求（单个）
     */
    @PostMapping("uploadFile")
    public ResponseResult<SystemUploadVO> uploadFile(MultipartFile file) {
        return ResponseResult.ok(upload(file));
    }

    /**
     * 通用上传请求（多个）
     */
    @PostMapping("uploadFiles")
    public ResponseResult<List<SystemUploadVO>> uploadFiles(List<MultipartFile> files){
        List<SystemUploadVO> dataList = new ArrayList<>();
        for (MultipartFile file : files) {
            dataList.add(upload(file));
        }
        return ResponseResult.ok(dataList);
    }

    @PostMapping("uploadFileWithWangEditor")
    public JSONObject uploadFileWithWangEditor(@RequestParam("file") MultipartFile file){
        JSONObject result = new JSONObject();
        try {
            SystemUploadVO systemUploadVO = upload(file);
            JSONObject data = new JSONObject();
            data.put("url", systemUploadVO.getUrl());
            data.put("alt", file.getOriginalFilename());
            data.put("href", "");
            result.put("errno", 0);
            result.put("data", data);
        } catch (Exception e) {
            result.put("errno", 1);
            result.put("message", "上传失败");
        }
        return result;
    }

    @SneakyThrows
    public SystemUploadVO upload(MultipartFile multipartFile) {
        String dir = "/" + sdf.format(new Date());
        // 原始文件名
        String originalFilename = multipartFile.getOriginalFilename();
        // 原始文件扩展名
        String offlater = originalFilename.substring(originalFilename.lastIndexOf("."));
        String newFile = IdUtil.getSnowflakeNextIdStr() + offlater;

        // F://temp/images    // F://temp/images/
        File targetPath = new File(uploadDir + Constants.RESOURCE_PREFIX + dir);
        if (!targetPath.exists()) {
            targetPath.mkdirs();
        }
        File targetFile = new File(targetPath, newFile);
        multipartFile.transferTo(targetFile);
        String filename = dir + "/" + newFile;
        SystemUploadVO systemUploadVO = SystemUploadVO.builder()
                .url(host + Constants.RESOURCE_PREFIX + filename)
                .newFileName(newFile)
                .originalFileName(originalFilename)
                .suffix(offlater)
                .size(multipartFile.getSize())
                .build();
        return systemUploadVO;
    }

    /**
     * 本地资源通用下载
     */
    @GetMapping("/download")
    public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response) throws IOException {
        if (resource.contains("..")) {
            throw new RuntimeException(StrUtil.format("资源文件({})非法，不允许下载。 ", resource));
        }
        // 数据库资源地址
        String downloadPath = uploadDir + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX);
        // 下载名称
        String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        FileUtils.setAttachmentResponseHeader(response, downloadName);
        FileUtils.writeBytes(downloadPath, response.getOutputStream());
    }

}
